`timescale 1ns / 1ps
`include "/team/riscv/rtl/riscv.h"
module cpu_core_test1;

    parameter BPS_115200 = 8680 ; //8680nsÃ¿bit
    parameter ClockPeriod = (1000/`FREQ);

    reg clk,rstn;

    always #(ClockPeriod/2) clk =~clk ;
    
    cpu_core_top uut(
        .clk (clk),
        .rstn(rstn),
        .i_intFlag_5(5'b0)
    );
function [31:0] getData;
        input [31:0] rnum;
        begin
            getData = {uut.socmem.dcache.Memory_byte3[rnum],uut.socmem.dcache.Memory_byte2[rnum],uut.socmem.dcache.Memory_byte1[rnum],uut.socmem.dcache.Memory_byte0[rnum]};
        end
endfunction   

function [0:0] comp;
        input [31:0] mem_data_over [8191:0];
        input [31:0] mem_data_ref [8191:0];
        reg flag;integer i;
        begin
            flag = 1;
             for (i = 0; i < 8192; i = i + 1) begin
                if(mem_data_over[i] != mem_data_ref[i]) flag = 0;
            end
            comp = flag;
        end
endfunction        

    wire[31:0] ex_end_flag     = {uut.socmem.dcache.Memory_byte3[1024+4],uut.socmem.dcache.Memory_byte2[1024+4],uut.socmem.dcache.Memory_byte1[1024+4],uut.socmem.dcache.Memory_byte0[1024+4]};
    wire[31:0] begin_signature = {uut.socmem.dcache.Memory_byte3[1024+2],uut.socmem.dcache.Memory_byte2[1024+2],uut.socmem.dcache.Memory_byte1[1024+2],uut.socmem.dcache.Memory_byte0[1024+2]};
    wire[31:0] end_signature   = {uut.socmem.dcache.Memory_byte3[1024+3],uut.socmem.dcache.Memory_byte2[1024+3],uut.socmem.dcache.Memory_byte1[1024+3],uut.socmem.dcache.Memory_byte0[1024+3]};

    reg [31:0] mem_inst [8191:0];
    reg [31:0] mem_data [8191:0];

    reg [31:0] mem_data_over [8191:0];
    reg [31:0] mem_data_ref [8191:0];

    integer i,roms,rownum,passnum,failnum;
    reg flag; reg [31:0] r;
    string str;
    string instdata = "/team/riscv/SDK/code/ISA-test/test2/build_generated";
    string refdata = "/team/riscv/SDK/code/ISA-test/test2/riscv-test-suite";

	
initial begin $sdf_annotate("../DC/output/cpu_core_top.sdf",uut); end 
initial
    begin
	clk=1'b0;
	roms = $fopen("/team/riscv/roms/roms2.txt","r");
        while(!$feof(roms))begin
			$fgets(str,roms);
			str = str.substr(0, str.len()-2);
			
            for(i=0;i<8192;i=i+1)begin
				mem_inst[i] = 0;
				mem_data[i] = 0;
                mem_data_over[i] = 0;
                mem_data_ref[i] = 0;
			end
	        $readmemh($sformatf("%s%s%s",instdata,str,".elf.inst.txt"),mem_inst);
            $readmemh($sformatf("%s%s%s",instdata,str,".elf.data.txt"),mem_data);
            $readmemh($sformatf("%s%s%s",refdata,str,".reference_output"),mem_data_ref);

			for(i = 0;i < 8192;i=i+1)begin
				uut.socmem.icache.Memory_byte3[i] = mem_inst[i][31:24];
				uut.socmem.icache.Memory_byte2[i] = mem_inst[i][23:16];
				uut.socmem.icache.Memory_byte1[i] = mem_inst[i][15:8];
				uut.socmem.icache.Memory_byte0[i] = mem_inst[i][7:0];
				
				uut.socmem.dcache.Memory_byte3[i] = mem_data[i][31:24];
				uut.socmem.dcache.Memory_byte2[i] = mem_data[i][23:16];
				uut.socmem.dcache.Memory_byte1[i] = mem_data[i][15:8];
				uut.socmem.dcache.Memory_byte0[i] = mem_data[i][7:0];
			end
			
			rstn = 1'b1;
			#23333
            rstn=1'b0;
            #23333
            rstn=1'b1;
            wait(ex_end_flag == 32'h1);
            //$stop;
            #100
            $display("==================================");
            $display("%7dns: %s",$time(),str);
            rownum = 0;passnum = 0;failnum = 0;
            for (r = begin_signature; r < end_signature; r = r + 4) begin
                mem_data_over[rownum] = getData(r[14:2]);
                flag = (mem_data_ref[rownum] == getData(r[14:2]));

                if(flag) begin passnum = passnum + 1; end else begin failnum = failnum + 1; end
        
                $display("%d\t%d\t%h\t%h\t%d",rownum,r[14:2],getData(r[14:2]),mem_data_ref[rownum],flag );
                rownum = rownum + 1;
            end
            //$stop;
               $display("%s: PASS %d ,FAIL %d ,PER %.2f%%",str, passnum, failnum, (passnum * 1.0)/( (passnum+failnum)*1.0 )*100 );
            $display("==================================");
          end
	$finish;

    end

endmodule
